home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / programming / other / scm / slib / yasyn.scm < prev   
Text File  |  1999-04-19  |  5KB  |  202 lines

  1. ;;"yasyn.scm" YASOS in terms of "object.scm"
  2. ;;;From: whumeniu@datap.ca (Wade Humeniuk)
  3.  
  4. (require 'object)
  5.  
  6. (define yasos:instance?     object?)
  7. ;; Removed (define yasos:make-instance 'bogus)  ;;
  8. ;; Removed (define-syntax YASOS:INSTANCE-DISPATCHER  ;; alias so compiler can inline for speed
  9. ;;   (syntax-rules () ((yasos:instance-dispatcher inst) (cdr inst))))
  10. ;; DEFINE-OPERATION
  11.  
  12. (define-syntax define-operation
  13.   (syntax-rules ()
  14.     ((define-operation (<name> <inst> <arg> ...) <exp1> <exp2> ...)
  15.      ;;=>
  16.      (define <name> (make-generic-method
  17.              (lambda (<inst> <arg> ...) <exp1> <exp2> ...))))
  18.  
  19.     ((define-operation (<name> <inst> <arg> ...) ) ;; no body
  20.      ;;=>
  21.      (define-operation (<name> <inst> <arg> ...)
  22.        (slib:error "Operation not handled"
  23.            '<name>
  24.            (format #f (if (yasos:instance? <inst>) "#<INSTANCE>" "~s")
  25.                <inst>))))))
  26.  
  27. ;; DEFINE-PREDICATE
  28.  
  29. (define-syntax define-predicate
  30.   (syntax-rules ()
  31.     ((define-predicate <name>)
  32.      ;;=>
  33.      (define <name> (make-generic-predicate)))))
  34.  
  35. ;; OBJECT
  36.  
  37. (define-syntax object
  38.   (syntax-rules ()
  39.     ((object ((<name> <self> <arg> ...) <exp1> <exp2> ...) ...)
  40.     ;;=>
  41.      (let ((self (make-object)))
  42.        (make-method! self <name> (lambda (<self> <arg> ...) <exp1> <exp2> ...))
  43.        ...
  44.        self))))
  45.  
  46. ;; OBJECT with MULTIPLE INHERITANCE  {First Found Rule}
  47.  
  48. (define-syntax object-with-ancestors
  49.   (syntax-rules ()
  50.     ((object-with-ancestors ( (<ancestor1> <init1>) ... ) 
  51.                 ((<name> <self> <arg> ...) <exp1> <exp2> ...) ...)
  52.     ;;=>
  53.      (let* ((<ancestor1> <init1>)
  54.         ...
  55.         (self (make-object <ancestor1> ...)))
  56.        (make-method! self <name> (lambda (<self> <arg> ...) <exp1> <exp2> ...))
  57.        ...
  58.        self))))
  59.        
  60. ;; OPERATE-AS  {a.k.a. send-to-super}
  61.  
  62. ; used in operations/methods
  63.  
  64. (define-syntax operate-as
  65.   (syntax-rules ()
  66.    ((operate-as <component> <op> <composit> <arg> ...) ;; What is <composit> ???
  67.    ;;=>
  68.     ((get-method <component> <op>) <composit> <arg> ...))))
  69.  
  70.  
  71.  
  72. ;; SET & SETTER
  73.  
  74.  
  75. (define-syntax set
  76.   (syntax-rules ()
  77.     ((set (<access> <index> ...) <newval>)
  78.      ((yasos:setter <access>) <index> ... <newval>)
  79.     )
  80.     ((set <var> <newval>)
  81.      (set! <var> <newval>)
  82.     )
  83. ) )
  84.  
  85.  
  86. (define yasos:add-setter    'bogus)
  87. (define yasos:remove-setter-for 'bogus)
  88.  
  89. (define yasos:setter
  90.   (let ( (known-setters (list (cons car set-car!)
  91.                   (cons cdr set-cdr!)
  92.                   (cons vector-ref vector-set!)
  93.                   (cons string-ref string-set!))
  94.      )
  95.      (added-setters '())
  96.        )
  97.  
  98.     (set! YASOS:ADD-SETTER
  99.       (lambda (getter setter)
  100.     (set! added-setters (cons (cons getter setter) added-setters)))
  101.     )
  102.     (set! YASOS:REMOVE-SETTER-FOR
  103.       (lambda (getter)
  104.     (cond
  105.       ((null? added-setters)
  106.        (slib:error "REMOVE-SETTER-FOR: Unknown getter" getter)
  107.       )
  108.       ((eq? getter (caar added-setters))
  109.        (set! added-setters (cdr added-setters))
  110.       )
  111.       (else
  112.         (let loop ((x added-setters) (y (cdr added-setters)))
  113.           (cond
  114.         ((null? y) (slib:error "REMOVE-SETTER-FOR: Unknown getter"
  115.                        getter))
  116.         ((eq? getter (caar y)) (set-cdr! x (cdr y)))
  117.         (else (loop (cdr x) (cdr y)))
  118.       ) ) )
  119.      ) ) )
  120.  
  121.     (letrec ( (self
  122.          (lambda (proc-or-operation)
  123.            (cond ((assq proc-or-operation known-setters) => cdr)
  124.              ((assq proc-or-operation added-setters) => cdr)
  125.              (else (proc-or-operation self))) )
  126.         ) )
  127.       self)
  128. ) )
  129.  
  130.  
  131.  
  132. (define (yasos:make-access-operation <name>)
  133.   (letrec ( (setter-dispatch
  134.            (lambda (inst . args)
  135.            (cond
  136.              ((and (yasos:instance? inst)
  137.                (get-method inst setter-dispatch))
  138.                => (lambda (method) (apply method (cons inst args)))
  139.              )
  140.              (else #f)))
  141.         )
  142.         (self
  143.            (lambda (inst . args)
  144.           (cond
  145.              ((eq? inst yasos:setter) setter-dispatch) ; for (setter self)
  146.              ((and (yasos:instance? inst)
  147.                (get-method inst self))
  148.               => (lambda (method) (apply method (cons inst args)))
  149.              )
  150.              (else (slib:error "Operation not handled" <name> inst))
  151.         )  )
  152.         )
  153.       )
  154.  
  155.       self
  156. ) )
  157.  
  158. (define-syntax define-access-operation
  159.   (syntax-rules ()
  160.     ((define-access-operation <name>)
  161.      ;=>
  162.      (define <name> (yasos:make-access-operation '<name>))
  163. ) ) )
  164.  
  165.  
  166.  
  167. ;;---------------------
  168. ;; general operations
  169. ;;---------------------
  170.  
  171. (define-operation (yasos:print obj port)
  172.   (format port
  173.       ;; if an instance does not have a PRINT operation..
  174.       (if (yasos:instance? obj) "#<INSTANCE>" "~s")
  175.       obj
  176. ) )
  177.  
  178. (define-operation (yasos:size obj)
  179.   ;; default behavior
  180.   (cond
  181.     ((vector? obj) (vector-length obj))
  182.     ((list?   obj) (length obj))
  183.     ((pair?   obj) 2)
  184.     ((string? obj) (string-length obj))
  185.     ((char?   obj) 1)
  186.     (else
  187.       (slib:error "Operation not supported: size" obj))
  188. ) )
  189.  
  190. (require 'format)
  191.  
  192. ;;; exports:
  193.  
  194. (define print yasos:print)        ; print also in debug.scm
  195. (define size yasos:size)
  196. (define add-setter yasos:add-setter)
  197. (define remove-setter-for yasos:remove-setter-for)
  198. (define setter yasos:setter)
  199.  
  200. (provide 'oop)                ;in case we were loaded this way.
  201. (provide 'yasos)
  202.